package com.example.opengltest1;

import android.opengl.GLES20;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;


public class Triangle {

    // 图形渲染管线（可编程）：顶点着色器 -> 几何着色器 -> 片段着色器
    // main函数外的变量：uniform（外部变量）、attribute（顶点变量）、varying（传递变量）
    // main函数内的变量：gl_Position(顶点着色器中必须赋值)、gl_FragColor(片段着色器中必须赋值)

    // 顶点着色器程序代码
    private final String vertexShaderCode =
            "uniform mat4 uMVPMatrix;" +
            "attribute vec4 vPosition;" +
             "void main() {" +
             "    gl_Position = uMVPMatrix * vPosition;" +
             "}";
    // 片段着色器程序代码
    private final String fragmentShaderCode =
            "precision mediump float;" +    // 精度说明
             "uniform vec4 vColor;" +
             "void main() {" +
             "    gl_FragColor = vColor;" +
             "}";

    private FloatBuffer vertexBuffer;

    static final int COORDS_PER_VERTEX = 3;
    static float triangleCoords[] = {
             0.0f,  0.5f,  0.0f,    // top
            -0.5f, -0.5f,  0.0f,    // bottom left
             0.5f, -0.5f,  0.0f     // bottom right
    };
    // set R, G, B, Alpha
    float color[] = {255, 0, 0, 1.0f};

    private final int mProgram;
    public Triangle() {
        // 分配内存
        ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
        // 调整大小端
        bb.order(ByteOrder.nativeOrder());
        // 获取顶点缓冲区
        vertexBuffer = bb.asFloatBuffer();
        // 向顶点缓冲区加入数据
        vertexBuffer.put(triangleCoords);
        // 确定起始位置
        vertexBuffer.position(0);

        // 获取顶点着色器
        int vertexShader = OneGlRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
        // 获取片段着色器
        int fragmentShader = OneGlRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
        // 创建项目（用于附加着色器）
        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, vertexShader);
        GLES20.glAttachShader(mProgram, fragmentShader);
        // 链接项目
        GLES20.glLinkProgram(mProgram);
    }

    private int mPositionHandle;
    private int mColorHandle;

    private int mMVPMatrixHandle;

    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
    private final int vertexStride = COORDS_PER_VERTEX * 4;

    public void draw(float[] mvpMatrix) {
        // 使用项目
        GLES20.glUseProgram(mProgram);
        // 获取顶点着色器的位置句柄
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        // 启用顶点着色器的位置句柄
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        // 准备图形坐标数据
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
        // 获取片段着色器的颜色句柄
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        // 准备图形颜色数据
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);
        // 绘制图形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
        // 关闭顶点着色器的位置句柄
        GLES20.glDisableVertexAttribArray(mPositionHandle);

        // 获取变化矩阵的数据句柄
        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        // 准备变换矩阵数据
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
        // 绘制图形，第一个参数是指定基本图元以何种方式组装
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
        // 关闭顶点着色器的位置句柄
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
}
